module LightV3_ip (
  output        SCK,
  output        SCS,
  output        SDI,
  input         SDO,
  input         sys_clock,
  input         bus_clock,
  input         resetn,
  input         stop,
  input  [1:0]  mem_ahb_htrans,
  input         mem_ahb_hready,
  input         mem_ahb_hwrite,
  input  [31:0] mem_ahb_haddr,
  input  [2:0]  mem_ahb_hsize,
  input  [2:0]  mem_ahb_hburst,
  input  [31:0] mem_ahb_hwdata,
  output tri1   mem_ahb_hreadyout,
  output        mem_ahb_hresp,
  output [31:0] mem_ahb_hrdata,
  output        slave_ahb_hsel,
  output tri1   slave_ahb_hready,
  input         slave_ahb_hreadyout,
  output [1:0]  slave_ahb_htrans,
  output [2:0]  slave_ahb_hsize,
  output [2:0]  slave_ahb_hburst,
  output        slave_ahb_hwrite,
  output [31:0] slave_ahb_haddr,
  output [31:0] slave_ahb_hwdata,
  input         slave_ahb_hresp,
  input  [31:0] slave_ahb_hrdata,
  output [3:0]  ext_dma_DMACBREQ,
  output [3:0]  ext_dma_DMACLBREQ,
  output [3:0]  ext_dma_DMACSREQ,
  output [3:0]  ext_dma_DMACLSREQ,
  input  [3:0]  ext_dma_DMACCLR,
  input  [3:0]  ext_dma_DMACTC,
  output [3:0]  local_int
);

parameter ADDR_BITS = 16;
parameter DATA_BITS = 32;

wire              apb_psel;   
wire              apb_penable;
wire              apb_pwrite;
wire      [15:0]  apb_paddr;
wire      [31:0]  apb_pwdata; 
reg       [31:0]  apb_prdata;

assign apb_clock = bus_clock;
assign local_int = 4'b0;

ahb2apb #(ADDR_BITS, DATA_BITS) ahb2apb_inst(
  .reset        (!resetn                     ),
  .ahb_clock    (sys_clock                   ),
  .ahb_hmastlock(1'b0                        ),
  .ahb_htrans   (mem_ahb_htrans              ),
  .ahb_hsel     (1'b1                        ),
  .ahb_hready   (mem_ahb_hready              ),
  .ahb_hwrite   (mem_ahb_hwrite              ),
  .ahb_haddr    (mem_ahb_haddr[ADDR_BITS-1:0]),
  .ahb_hsize    (mem_ahb_hsize               ),
  .ahb_hburst   (mem_ahb_hburst              ),
  .ahb_hprot    (4'b0011                     ),
  .ahb_hwdata   (mem_ahb_hwdata              ),
  .ahb_hrdata   (mem_ahb_hrdata              ),
  .ahb_hreadyout(mem_ahb_hreadyout           ),
  .ahb_hresp    (mem_ahb_hresp               ),
  .apb_clock    (apb_clock                   ),
  .apb_psel     (apb_psel                    ),
  .apb_penable  (apb_penable                 ),
  .apb_pwrite   (apb_pwrite                  ),
  .apb_paddr    (apb_paddr                   ),
  .apb_pwdata   (apb_pwdata                  ),
  .apb_pstrb    (                            ),
  .apb_pprot    (                            ),
  .apb_pready   (1'b1                        ),
  .apb_pslverr  (1'b0                        ),
  .apb_prdata   (apb_prdata                  )
);
//---------------------------------------------
//-- 寄存器
//---------------------------------------------
assign wen = apb_psel&apb_penable&apb_pwrite;
assign ren = apb_psel&(~apb_pwrite)&(~apb_penable);

reg [7:0]  apb_pwdata_r;
reg [0:0]  tx_fifo_rdreq=1'b0;
reg [0:0]  tx_fifo_wreq=1'b0;
wire[0:0]  tx_fifo_empty;
reg [2:0]  tx_fifo_empty_r;
wire[7:0]  tx_fifo_q;
reg [0:0]  csen=1'b1;
wire[0:0]  tx_req;
reg [0:0]  tx_fifo_rdreq_r=1'b0;
reg [0:0]  tx_en=1'b0;
reg [7:0]  tx_data;
reg [0:0]  done=1'b1;
wire[0:0]  rx_en;
wire[7:0]  rx_data;
wire[9:0]  usedw;
reg [0:0]  rx_fifo_req=1'b0;
wire[7:0]  rx_fifo_q;

reg [0:0]  rx_fifo_wen=1'b0;
reg [7:0]  rx_fifo_data=0;

reg [0:0]  rx_fifo_wen_r=1'b0;
reg [7:0]  rx_fifo_data_r=0;
//---------------------------------------------
//-- 发送数据fifo
//---------------------------------------------
tx_fifo tx_fifo_inst(
	.clock      (apb_clock    ),
	.data       (apb_pwdata_r ),
	.rdreq      (tx_fifo_rdreq),
	.wrreq      (tx_fifo_wreq ),
	.empty      (tx_fifo_empty),
	.q          (tx_fifo_q    ));


always@(posedge apb_clock)                            //-fifo空延拍                  
begin
  tx_fifo_empty_r <= {tx_fifo_empty_r[1:0],tx_fifo_empty};
end

	
always@(posedge apb_clock)                            //--fifo 写使能
begin
  if((wen==1'b1) && (apb_paddr[15]==1'b0))             
    tx_fifo_wreq <= 1'b1;
  else
    tx_fifo_wreq <= 1'b0;
end

always@(posedge apb_clock)                            //--fifo写数据
begin
    apb_pwdata_r <= apb_pwdata[7:0];
end

always@(posedge apb_clock)                            //--fifo读使能             
begin
  if((tx_req==1'b1) && (tx_fifo_empty==1'b0))
    tx_fifo_rdreq <= 1'b1;
  else
    tx_fifo_rdreq <= 1'b0;
end

always@(posedge apb_clock)                           
begin
  tx_fifo_rdreq_r <= tx_fifo_rdreq;
end

//---------------------------------------------
//-- 接收数据fifo
//---------------------------------------------
rx_fifo rx_fifo_inst(
	.clock      (apb_clock     ),
	.data       (rx_fifo_data_r),
	.rdreq      (rx_fifo_req   ),
	.wrreq      (rx_fifo_wen_r ),
	.q          (rx_fifo_q     ),
	.usedw      (usedw         )
);

always@(posedge apb_clock)                           
begin
  if((apb_paddr[15]==1'b0)&&(ren==1'b1))
    rx_fifo_req <= 1'b1;
  else
    rx_fifo_req <= 1'b0;
end

always@(posedge apb_clock)                           
begin
  rx_fifo_wen    <= rx_en;
  rx_fifo_data   <= rx_data;
  rx_fifo_wen_r  <= rx_fifo_wen;
  rx_fifo_data_r <= rx_fifo_data;
end

always@(posedge apb_clock)                           
begin
  if((apb_paddr[15]==1'b0)&&(ren==1'b1))                               //-读fifo数据
    apb_prdata <= {24'd0,rx_fifo_q};
  else if((apb_paddr[15]==1'b1)&&(apb_paddr[1:0]==2'b00)&&(ren==1'b1)) //-读数据个数
    apb_prdata <= {22'd0,usedw};
end

//---------------------------------------------
//-- spi tx rx
//---------------------------------------------
spi spi_inst(
   .clk        (apb_clock   ),
   .csen       (csen        ),               
   .tx_req     (tx_req      ),        
   .tx_en      (tx_en       ),        
   .tx_data    (tx_data     ),        
   .rx_en      (rx_en       ),        
   .rx_data    (rx_data     ),
   .scs        (SCS         ),	
   .sck        (SCK         ),
   .sdi        (SDI         ),
   .sdo        (SDO         )
);

always@(posedge apb_clock)                          //-csen                   
begin
  csen <= tx_fifo_empty_r[2];
end

always@(posedge apb_clock)                           
begin
  tx_en   <= tx_fifo_rdreq_r;
  tx_data <= tx_fifo_q;
end


endmodule
